/*
 *  Copyright (c) 2022 ZhuHai Jieli Technology Co.,Ltd.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include "event.h"
#include "timer.h"
#include "os_api.h"
#include "ohos_bt_def.h"
#include "ohos_bt_gatt.h"
#include "ohos_bt_gatt_server.h"
#include "ohos_bt_gatt_client.h"
#include "le_common.h"

static int clientId;
static BdAddr local_addr, remote_addr;
static BtGattCallbacks gatt_func = {NULL};
static BtGattServerCallbacks gatts_func = {NULL};
static BtGattClientCallbacks gattc_func = {NULL};

static void BleAdvEnableCallback(int advId, int status)
{
    printf("^^^%s, status = %d\n", __FUNCTION__, status);
}

static void BleAdvDisableCallback(int advId, int status)
{
    printf("^^%s, status = %d\n", __FUNCTION__, status);
}

static void BleAdvDataCallback(int advId, int status)
{
    printf("^^^%s, status = %d\n", __FUNCTION__, status);
}

static void BleAdvUpdateCallback(int advId, int status)
{
    printf("^^^ %s, status = %d\n", __FUNCTION__, status);
}

static void BleConnectServerCallback(int connId, int serverId, const BdAddr *bdAddr)
{
    printf("^^^%s, connId = %d\n", __FUNCTION__, connId);
}

static void BleDisconnectServerCallback(int connId, int serverId, const BdAddr *bdAddr)
{
    printf("^^^%s, connId = %d\n", __FUNCTION__, connId);
}

static void BleMtuChangeCallback(int connId, int mtu)
{
    printf("^^^%s, connId = %d, mtu = %d\n", __FUNCTION__, connId, mtu);
}

static void BleConnectionStateChangedCallback(int clientId, int connectionState, int status)
{
    printf("^^^%s, connect_state = %d\n", __FUNCTION__, connectionState);

    switch (connectionState) {
        case OHOS_STATE_CONNECTING:
            break;
        case OHOS_STATE_CONNECTED:
            BleGattcSearchServices(clientId);
            break;
        case OHOS_STATE_DISCONNECTING:
            break;
        case OHOS_STATE_DISCONNECTED:
            break;
        default:
            break;
    }
}

static void BleConnectParaUpdateCallback(int clientId, int interval, int latency, int timeout, int status)
{
    printf("^^^%s, interval = %d, latency = %d, timeout = %d\n", __FUNCTION__, interval, latency, timeout);
}

static void BleSearchServiceCompleteCallback(int clientId, int status)
{
    printf("^^^%s\n", __FUNCTION__);
}

static void BleScanResultCallback(BtScanResultData *scanResultdata)
{
    u8 dest_addr[6] = {0xA4, 0xCB, 0x3C, 0xA8, 0x90, 0x44};
    
    printf("^^^%s, rssi = %d, addr = %X:%X:%X:%X:%X:%X\n", __FUNCTION__, scanResultdata->rssi, \
            scanResultdata->addr.addr[0], scanResultdata->addr.addr[1], scanResultdata->addr.addr[2], \
            scanResultdata->addr.addr[3], scanResultdata->addr.addr[4], scanResultdata->addr.addr[5]);
    if (!memcmp(scanResultdata->addr.addr, dest_addr, OHOS_BD_ADDR_LEN)) {
        printf("match dest_addr\n");
        BleStopScan();
        gattc_func.ConnectionStateCb       = BleConnectionStateChangedCallback;
        gattc_func.connectParaUpdateCb     = BleConnectParaUpdateCallback;
        gattc_func.searchServiceCompleteCb = BleSearchServiceCompleteCallback;
        BleGattcConnect(clientId, &gattc_func, dest_addr, 1, 0);
    }
}

static void BleScanParameterSetCompletedCallback(int clientId, int status)
{
    printf("^^^ %s, status = %d\n", __FUNCTION__, status);
}

void ble_demo_run(void)
{
    BtUuid id;
    u8 name[] = "JL_OHOS";
    u8 offset, adv_data[31] = {0}, rsp_data[31] = {0};
    BleAdvParams adv_params = {0};
    StartAdvRawData raw_data = {0};
    BleScanParams scan_params = {0};

    os_adapter_init();
    sys_event_init();
    sys_timer_init();

    adc_init();

    InitBtStack();
    EnableBtStack();
    SetDeviceName(name, strlen(name));

    // gatt client
    gatt_func.scanResultCb   = BleScanResultCallback;
    gatt_func.scanParamSetCb = BleScanParameterSetCompletedCallback;
    BleGattRegisterCallbacks(&gatt_func);
    clientId = BleGattcRegister(id);
    printf(">>>>>>clientId = %d\n", clientId);

    scan_params.scanInterval = 24 * 8 / 5;
    scan_params.scanWindow   = 8 * 8 / 5;
    scan_params.scanType     = 1;
    BleSetScanParameters(0, &scan_params);
    BleStartScan();
}
